package com.kotlin.android.api

import com.kotlin.android.api.api.Api
import com.kotlin.android.api.config.AppConfig
import com.kotlin.android.api.config.Env
import com.kotlin.android.api.converter.NullOnEmptyConverterFactory
import com.kotlin.android.api.converter.WandaConverterFactory
import com.kotlin.android.api.header.ApiHeader
import com.kotlin.android.api.header.storeToken
import com.kotlin.android.api.key.ApiKey
import com.kotlin.android.api.ssl.SSL
import com.kotlin.android.api.ssl.UnSafeHostnameVerifier
import com.kotlin.android.ktx.ext.d
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import java.util.concurrent.TimeUnit

/**
 *
 * Created on 2020-01-10.
 *
 * @author o.s
 */
object RetrofitManager {

    fun retrofit(baseUrl: String = Env.instance.hostMisc): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(NullOnEmptyConverterFactory.create())
            .addConverterFactory(WandaConverterFactory.create())
            .baseUrl(baseUrl)
            .client(client())
            .build()
    }

    fun <T : Any> api(service: Class<T>): T {
        return ApiRepository.instance.getApi(service)
    }

    fun api(): Api {
        return api(Api::class.java)
    }

    private fun client(): OkHttpClient {
        logInterceptor.level = HttpLoggingInterceptor.Level.BODY

        val builder = OkHttpClient.Builder()
            .connectTimeout(5000L, TimeUnit.MILLISECONDS)
            .readTimeout(10_000, TimeUnit.MILLISECONDS)
            .writeTimeout(30_000, TimeUnit.MILLISECONDS)
            .addInterceptor(interceptor)
            .addInterceptor(logInterceptor)
        setupSSL(builder)

        return builder.build()
    }

    private fun setupSSL(builder: OkHttpClient.Builder) {
        if (ApiKey.QAS != AppConfig.instance.api) {
            builder.hostnameVerifier(UnSafeHostnameVerifier())
            SSL.instance.ssl?.apply {
                builder.sslSocketFactory(sslSocketFactory, trustManager)
            }
        }
    }

    private val interceptor = Interceptor {
        var request: Request
        it.request().apply {
            request = newBuilder().headers(ApiHeader.getHeaders(url, method, body)).build()
            "request url :: ${request.url}".d()
        }
        val response = it.proceed(request)
        storeToken(response)
        response
    }

    private val logInterceptor = HttpLoggingInterceptor(
        object : HttpLoggingInterceptor.Logger {
            override fun log(message: String) {
            }
        }
    )
}